/**
 *
 */
package com.leehom.arch.base.utils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 类名: DTOUtils
 * 说明: DTO工具类
 *
 * @author leehom
 * @Date Nov 30, 2009 4:09:36 PM
 * 修改记录：
 * @see
 */
public class DTOUtils {
	
	private static Logger log = LoggerFactory.getLogger(DTOUtils.class);

    /**
     * @param maps
     * @param clazz 对象类型
     * @return
     * @throws Exception
     */
    public static List<Object> maps2DTOs(List<Map<String, Object>> maps, Class clazz) throws Exception {
        List<Object> dtos = new ArrayList<Object>();
        for (Map<String, Object> m : maps) {
            Object obj = clazz.newInstance();
            map2DTO(m, obj);
            dtos.add(obj);
        }
        return dtos;
    }
    
    public static Object map2DTO(Map<String, Object> map, Object o) throws Exception {
        if (!map.isEmpty()) {
            Method[] methods = o.getClass().getDeclaredMethods();
            Map<String, Method> methodMap = new HashMap<>();
            if (methods != null) {
                for (Method method : methods) {
                    methodMap.put(method.getName(), method);
                }
            }
            // 遍历Map
            for (String k : map.keySet()) {
            	log.debug("*******map2dto, key: [{}]", k);
                Object v = map.get(k);
                Field[] fields = o.getClass().getDeclaredFields();
                //
                for (Field field : fields) {
                    String fieldSetName = parSetName(field.getName());
                    if (!checkSetMet(methods, fieldSetName)) {
                        continue;
                    }

                    Method fieldSetMet = methodMap.get(fieldSetName);

                    int mod = field.getModifiers();
                    // 静态、final方法
                    if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                        continue;
                    }

                    if (field.getName().equalsIgnoreCase(k)) {
                        field.setAccessible(true);
                        fieldSetMet.invoke(o, v);
                        break;
                    }

                }
            }
        }
        return o;
    }
    
    public static Object map2DTO2(Map<String, Object> map, Object o) throws Exception {
        if (!map.isEmpty()) {
            Method[] methods = o.getClass().getDeclaredMethods();
            Map<String, Method> methodMap = new HashMap<>();
            if (methods != null) {
                for (Method method : methods) {
                    methodMap.put(method.getName(), method);
                }
            }
            // 遍历Map
            for (String k : map.keySet()) {
            	log.debug("*******map2dto, key: [{}]", k);
                Object v = map.get(k);
                Field[] fields = o.getClass().getDeclaredFields();
                //
                for (Field field : fields) {
                    String fieldSetName = parSetName(field.getName());
                    if (!checkSetMet(methods, fieldSetName)) {
                        continue;
                    }

                    Method fieldSetMet = methodMap.get(fieldSetName);

                    int mod = field.getModifiers();
                    // 静态、final方法
                    if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                        continue;
                    }

                    if (field.getName().equalsIgnoreCase(k)) {
                        field.setAccessible(true);
                        fieldSetMet.invoke(o, v);
                        break;
                    }

                }
            }
        }
        return o;
    }

    /**
     * 说明：获取DTO属性名称，遵循java bean规范
     *
     * @param beanClass
     * @return 异常：
     * @author leehom
     */
    public static String[] getFieldName(Class<? extends Object> beanClass) {
        //
        Method[] methods = beanClass.getDeclaredMethods();
        String fieldName;
        String methodName;
        /** */
        List<String> l = new ArrayList<String>();
        for (int i = 0; i <= methods.length - 1; i++) {
            methodName = methods[i].getName();
            if (!methodName.startsWith("get") || methodName.equals("get"))
                continue;
            fieldName = methodName.substring(3, 4).toLowerCase() + methodName.substring(4);
            l.add(fieldName);
        }
        return l.toArray(new String[]{});
    }
    
    public static String parSetName(String fieldName) {
        if (null == fieldName || "".equals(fieldName)) {
            return null;
        }
        int startIndex = 0;
        if (fieldName.charAt(0) == '_')
            startIndex = 1;
        return "set"
                + fieldName.substring(startIndex, startIndex + 1).toUpperCase()
                + fieldName.substring(startIndex + 1);
    }

    public static boolean checkSetMet(Method[] methods, String fieldSetMet) {
        for (Method met : methods) {
            if (fieldSetMet.equals(met.getName())) {
                return true;
            }
        }
        return false;
    }

}
